﻿//==============================================================================  
//Copyright (C) 2012-2015 9UN.ORG. All rights reserved. 
//GUID：46172595-6b69-4526-b9da-426d663f5b05
//CLR Version: 4.0.30319.18033
//Code Author：Kevin Wang
//Contact：Email(Admin@9un.org),QQ(265382 or 74344)
//Filename：DoubleWindowBase
//Namespace：RuanRang.Media.Core
//Functions：DoubleWindowBase  
//Created by Kevin Wang at 2013/2/2 23:05:09 http://blog.9un.org
//============================================================================== 

using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using RuanRang.Media.Core;
using RuanRang.Media.Core.Io;

namespace RuanRang.Media.WinForms
{
    /// <summary>
    /// User control represents a window can be used to render video.
    /// </summary>
    [ToolboxBitmap(typeof(VlcWindowControl), "vlc_icon.png")]
    public partial class VlcWindowControl : UserControl
    {
        private const int WM_LBUTTONDOWN = 0x0201;
        //按下鼠标左键

        private const int WM_LBUTTONUP = 0x0202;
        //释放鼠标左键

        private const int WM_LBUTTONDBLCLK = 0x0203;
        //双击鼠标左键

        private const int WM_MOUSEMOVE = 0x0200;

        // 移动鼠标
        private const int WM_SYSCOMMAND = 0x0112;
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_LBUTTONDOWN:
                    {
                        MessageBox.Show("WM_LBUTTONDOWN!");
                    }
                    break;
                case WM_LBUTTONUP:
                    {
                        MessageBox.Show("WM_LBUTTONUP!");
                    }
                    break;
                case WM_LBUTTONDBLCLK:
                    {
                        MessageBox.Show("WM_LBUTTONDBLCLK!");
                    }
                    break;
                case WM_MOUSEMOVE:
                    {
                        MessageBox.Show("WM_MOUSEMOVE!");
                    }
                    break;
                case WM_SYSCOMMAND:
                    {
                        MessageBox.Show("WM_SYSCOMMAND!");
                    }
                    break;
            }
            base.WndProc(ref m);
        }

        /// <summary>
        /// The _window
        /// </summary>
        private readonly VlcPlayerControlWindow _window;

        /// <summary>
        /// Default constructor.
        /// </summary>
        public VlcWindowControl()
        {
            InitializeComponent();
            //
            _window = new VlcPlayerControlWindow(panel1, panel2, panelHost, this);
        }

        /// <summary>
        /// Window can be passed to the VLC <see cref="Window" />
        /// </summary>
        /// <value>The window.</value>
        public MediaWindow Window
        {
            get
            {
                return (_window);
            }
        }

        /// <summary>
        /// Is player's subwindow visible on the control's surface.
        /// </summary>
        /// <value><c>true</c> if [player visible]; otherwise, <c>false</c>.</value>
        [Browsable(true)]
        public bool PlayerVisible
        {
            get
            {
                return (_window.Visible);
            }
            set
            {
                _window.Visible = value;
            }
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                _window.Dispose();
            }
            //
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Nested type : VlcPlayerControlWindow

        private sealed class VlcPlayerControlWindow : DoubleWindowBase
        {
            private readonly Panel _panel1;
            private readonly Panel _panel2;
            private readonly Panel _panelHost;
            private readonly VlcWindowControl _controlHost;

            private bool _isFirstPanelActive;
            private bool _isVisible;

            /// <summary>
            /// Initializes a new instance of the <see cref="VlcPlayerControlWindow" /> class.
            /// </summary>
            /// <param name="panel1">The panel1.</param>
            /// <param name="panel2">The panel2.</param>
            /// <param name="panelHost">The panel host.</param>
            /// <param name="control">The control.</param>
            /// <exception cref="System.ArgumentNullException">panel1
            /// or
            /// panel2
            /// or
            /// panelHost
            /// or
            /// control</exception>
            public VlcPlayerControlWindow(Panel panel1, Panel panel2, Panel panelHost, VlcWindowControl control)
            {
                if (panel1 == null)
                {
                    throw new ArgumentNullException("panel1");
                }
                if (panel2 == null)
                {
                    throw new ArgumentNullException("panel2");
                }
                if (panelHost == null)
                {
                    throw new ArgumentNullException("panelHost");
                }
                if (control == null)
                {
                    throw new ArgumentNullException("control");
                }
                //
                _panel1 = panel1;

                _panel2 = panel2;

                _panelHost = panelHost;

                _controlHost = control;
                //
                _isFirstPanelActive = true;
                // Default visibility is true
                _playerVisible = true;
                _isVisible = true;
                SetVisible(true);
            }

            public override bool Visible
            {
                get
                {
                    return (_isVisible);
                }
                set
                {
                    if (_isVisible == value) return;
                    _isVisible = value;
                    //
                    SetVisible(_isVisible);
                }
            }

            /// <summary>
            /// Sets the visible.
            /// </summary>
            /// <param name="visible">if set to <c>true</c> [visible].</param>
            private void SetVisible(bool visible)
            {
                if (!visible)
                {
                    SetPlayerVisible(false);
                    //
                    _panelHost.Visible = false;
                    _controlHost.Visible = false;
                }
                else
                {
                    _controlHost.Visible = true;
                    _panelHost.Visible = true;
                    //
                    SetPlayerVisible(_playerVisible);
                }
            }

            /// <summary>
            /// GETs the active panel.
            /// </summary>
            /// <returns>Panel.</returns>
            private Panel GetActivePanel()
            {
                return (_isFirstPanelActive ? _panel1 : _panel2);
            }

            /// <summary>
            /// GETs the inactive panel.
            /// </summary>
            /// <returns>Panel.</returns>
            private Panel GetInactivePanel()
            {
                return (_isFirstPanelActive ? _panel2 : _panel1);
            }

            /// <summary>
            /// Returns handle to first window handle.
            /// </summary>
            /// <returns>OS specific handle of window.</returns>
            protected override IntPtr GetActiveWindowHandle()
            {
                return (GetActivePanel().Handle);
            }

            /// <summary>
            /// Returns handle to second window handle.
            /// </summary>
            /// <returns>OS specific handle of window.</returns>
            protected override IntPtr GetInactiveWindowHandle()
            {
                return (GetInactivePanel().Handle);
            }

            /// <summary>
            /// Provides logic to switch between two windows.
            /// </summary>
            protected override void SwitchWindows()
            {
                _isFirstPanelActive = !_isFirstPanelActive;
                //
                SetVisible(_isVisible);
            }

            /// <summary>
            /// Width of window.
            /// </summary>
            /// <value>The width.</value>
            public override int Width
            {
                get
                {
                    return (_controlHost.Width);
                }
                set
                {
                    _controlHost.Width = value;
                }
            }

            /// <summary>
            /// Height of window.
            /// </summary>
            /// <value>The height.</value>
            public override int Height
            {
                get
                {
                    return (_controlHost.Height);
                }
                set
                {
                    _controlHost.Height = value;
                }
            }

            /// <summary>
            /// X coordinate of window.
            /// </summary>
            /// <value>The left.</value>
            public override int Left
            {
                get
                {
                    return (_controlHost.Left);
                }
                set
                {
                    _controlHost.Left = value;
                }
            }

            /// <summary>
            /// Y coordinate of window.
            /// </summary>
            /// <value>The top.</value>
            public override int Top
            {
                get
                {
                    return (_controlHost.Top);
                }
                set
                {
                    _controlHost.Top = value;
                }
            }

            /// <summary>
            /// Background color used to fill
            /// background of window.
            /// </summary>
            /// <value>The color of the background.</value>
            public override uint BackgroundColor
            {
                get
                {
                    return unchecked((uint)(_controlHost.BackColor.ToArgb()));
                }
                set
                {
                    _controlHost.BackColor = Color.FromArgb(unchecked((int)value));
                }
            }

            /// <summary>
            /// Path to background image path.
            /// </summary>
            /// <value>The background image file path.</value>
            /// <exception cref="System.NotSupportedException">Comming soon.
            /// or
            /// Comming soon.</exception>
            public override string BackgroundImageFilePath
            {
                get
                {
                    throw new NotSupportedException("Comming soon.");
                }
                set
                {
                    throw new NotSupportedException("Comming soon.");
                }
            }

            /// <summary>
            /// The _player visible
            /// </summary>
            private bool _playerVisible;

            /// <summary>
            /// Player visibility.
            /// </summary>
            /// <value><c>true</c> if [player visible]; otherwise, <c>false</c>.</value>
            protected override bool PlayerVisible
            {
                get
                {
                    return (_playerVisible);
                }
                set
                {
                    if (_playerVisible == value) return;
                    _playerVisible = value;
                    //
                    SetPlayerVisible(_playerVisible);
                }
            }

            /// <summary>
            /// Sets the player visible.
            /// </summary>
            /// <param name="isPlayerVisible">if set to <c>true</c> [is player visible].</param>
            private void SetPlayerVisible(bool isPlayerVisible)
            {
                var panel = GetInactivePanel();
                panel.SendToBack();
                _panelHost.Update();
            }
        }
        #endregion
    }
}